home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqbuild / qcc.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  14.1 KB  |  494 lines

  1. #ifndef    QCC_H
  2. #define    QCC_H
  3.  
  4. /*
  5.  * ============================================================================
  6.  * 
  7.  * TODO:
  8.  * 
  9.  * "stopped at 10 errors"
  10.  * 
  11.  * other pointer types for models and clients?
  12.  * 
  13.  * compact string heap?
  14.  * 
  15.  * allways initialize all variables to something safe
  16.  * 
  17.  * the def->type->type arrangement is really silly.
  18.  * 
  19.  * return type checking
  20.  * 
  21.  * parm count type checking
  22.  * 
  23.  * immediate overflow checking
  24.  * 
  25.  * pass the first two parms in call->b and call->c
  26.  * 
  27.  * ============================================================================
  28.  */
  29.  
  30. /*
  31.  * ============================================================================
  32.  * 
  33.  * comments
  34.  * --------
  35.  * // comments discard text until the end of line
  36.  * / *  * / comments discard all enclosed text (spaced out on this line because this documentation is in a regular C comment block, and typing them in normally causes a parse error)
  37.  * 
  38.  * code structure
  39.  * --------------
  40.  * A definition is:
  41.  * <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  42.  * 
  43.  * 
  44.  * types
  45.  * -----
  46.  * simple types: void, float, vector, string, or entity
  47.  * float                width, height;
  48.  * string               name;
  49.  * entity               self, other;
  50.  * 
  51.  * vector types:
  52.  * vector               org;    // also creates org_x, org_y, and org_z float defs
  53.  * 
  54.  * 
  55.  * A function type is specified as:     simpletype ( type name {,type name} )
  56.  * The names are ignored except when the function is initialized.       
  57.  * void()               think;
  58.  * entity()     FindTarget;
  59.  * void(vector destination, float speed, void() callback)       SUB_CalcMove;
  60.  * void(...)    dprint;         // variable argument builtin
  61.  * 
  62.  * A field type is specified as:  .type
  63.  * .vector              origin;
  64.  * .string              netname;
  65.  * .void()              think, touch, use;
  66.  * 
  67.  * 
  68.  * names
  69.  * -----
  70.  * Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
  71.  * 
  72.  * There are two levels of scoping: global, and function.  The parameter list of a function and any vars declared inside a function with the "local" statement are only visible within that function, 
  73.  * 
  74.  * 
  75.  * immediates
  76.  * ----------
  77.  * Float immediates must begin with 0-9 or minus sign.  .5 is illegal.
  78.  * 
  79.  * A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error.  Seperate the - from the digits with a space "a - 5" to get the proper behavior.
  80.  * 12
  81.  * 1.6
  82.  * 0.5
  83.  * -100
  84.  * 
  85.  * Vector immediates are three float immediates enclosed in single quotes.
  86.  * '0 0 0'
  87.  * '20.5 -10 0.00001'
  88.  * 
  89.  * String immediates are characters enclosed in double quotes.  The string cannot contain explicit newlines, but the escape character \n can embed one.  The \" escape can be used to include a quote in the string.
  90.  * "maps/jrwiz1.bsp"
  91.  * "sound/nin/pain.wav"
  92.  * "ouch!\n"
  93.  * 
  94.  * Code immediates are statements enclosed in {} braces.
  95.  * statement:
  96.  * { <multiple statements> }
  97.  * <expression>;
  98.  * local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  99.  * return <expression>;
  100.  * if ( <expression> ) <statement> [ else <statement> ];
  101.  * while ( <expression> ) <statement>;
  102.  * do <statement> while ( <expression> );
  103.  * <function name> ( <function parms> );
  104.  * 
  105.  * expression:
  106.  * combiations of names and these operators with standard C precedence:
  107.  * "&&", "||", "<=", ">=","==", "!=", "!", "*", "/", "-", "+", "=", ".", "<", ">", "&", "|"
  108.  * Parenthesis can be used to alter order of operation.
  109.  * The & and | operations perform integral bit ops on floats
  110.  * 
  111.  * A built in function immediate is a number sign followed by an integer.
  112.  * #1
  113.  * #12
  114.  * 
  115.  * 
  116.  * compilation
  117.  * -----------
  118.  * Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all other files.
  119.  * 
  120.  * The language is strongly typed and there are no casts.
  121.  * 
  122.  * Anything that is initialized is assumed to be constant, and will have immediates folded into it.  If you change the value, your program will malfunction.  All uninitialized globals will be saved to savegame files.
  123.  * 
  124.  * Functions cannot have more than eight parameters.
  125.  * 
  126.  * Error recovery during compilation is minimal.  It will skip to the next global definition, so you will never see more than one error at a time in a given function.  All compilation aborts after ten error messages.
  127.  * 
  128.  * Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
  129.  * 
  130.  * void()       MyFunction;                     // the prototype
  131.  * 
  132.  * void()       MyFunction =            // the initialization
  133.  * {
  134.  * dprint ("we're here\n");
  135.  * };
  136.  * 
  137.  * 
  138.  * entities and fields
  139.  * -------------------
  140.  * 
  141.  * 
  142.  * execution
  143.  * ---------
  144.  * Code execution is initiated by C code in quake from two main places:  the timed think routines for periodic control, and the touch function when two objects impact each other.
  145.  * 
  146.  * There are three global variables that are set before beginning code execution:
  147.  * entity       world;          // the server's world object, which holds all global
  148.  * // state for the server, like the deathmatch flags
  149.  * // and the body ques.
  150.  * entity       self;           // the entity the function is executing for
  151.  * entity       other;          // the other object in an impact, not used for thinks
  152.  * float        time;           // the current game time.  Note that because the
  153.  * // entities in the world are simulated sequentially,
  154.  * // time is NOT strictly increasing.  An impact late
  155.  * // in one entity's time slice may set time higher
  156.  * // than the think function of the next entity. 
  157.  * // The difference is limited to 0.1 seconds.
  158.  * Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
  159.  * 
  160.  * There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
  161.  * 
  162.  * It is acceptable to change the system set global variables.  This is usually done to pose as another entity by changing self and calling a function.
  163.  * 
  164.  * The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code.  All time consuming operations should be made into built in functions.
  165.  * 
  166.  * A profile counter is kept for each function, and incremented for each interpreted instruction inside that function.  The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters.  The "profile all" command will dump sorted stats for every function that has been executed.
  167.  * 
  168.  * 
  169.  * afunc ( 4, bfunc(1,2,3));
  170.  * will fail because there is a shared parameter marshaling area, which will cause the 1 from bfunc to overwrite the 4 allready placed in parm0.  When a function is called, it copies the parms from the globals into it's privately scoped variables, so there is no collision when calling another function.
  171.  * 
  172.  * total = factorial(3) + factorial(4);
  173.  * Will fail because the return value from functions is held in a single global area.  If this really gets on your nerves, tell me and I can work around it at a slight performance and space penalty by allocating a new register for the function call and copying it out.
  174.  * 
  175.  * 
  176.  * built in functions
  177.  * ------------------
  178.  * void(string text)    dprint;
  179.  * Prints the string to the server console.
  180.  * 
  181.  * void(entity client, string text)     cprint;
  182.  * Prints a message to a specific client.
  183.  * 
  184.  * void(string text)    bprint;
  185.  * Broadcast prints a message to all clients on the current server.
  186.  * 
  187.  * entity()     spawn;
  188.  * Returns a totally empty entity.  You can manually set everything up, or just set the origin and call one of the existing entity setup functions.
  189.  * 
  190.  * entity(entity start, .string field, string match) find;
  191.  * Searches the server entity list beginning at start, looking for an entity that has entity.field = match.  To start at the beginning of the list, pass world.  World is returned when the end of the list is reached.
  192.  * 
  193.  * <FIXME: define all the other functions...>
  194.  * 
  195.  * 
  196.  * gotchas
  197.  * -------
  198.  * 
  199.  * The && and || operators DO NOT EARLY OUT like C!
  200.  * 
  201.  * Don't confuse single quoted vectors with double quoted strings
  202.  * 
  203.  * The function declaration syntax takes a little getting used to.
  204.  * 
  205.  * Don't forget the ; after the trailing brace of a function initialization.
  206.  * 
  207.  * Don't forget the "local" before defining local variables.
  208.  * 
  209.  * There are no ++ / -- operators, or operate/assign operators.
  210.  * 
  211.  * ============================================================================
  212.  */
  213.  
  214. #define    MAX_ERRORS        10
  215. #define    MAX_NAME        64                           // chars long
  216. #define    MAX_REGS        16384
  217.  
  218. #define    MAX_FRAMES        256
  219.  
  220. #define    MAX_STRINGS        500000
  221. #define    MAX_GLOBALS        16384
  222. #define    MAX_FIELDS        1024
  223. #define    MAX_STATEMENTS        65536
  224. #define    MAX_FUNCTIONS        8192
  225.  
  226. #define    MAX_SOUNDS        1024
  227. #define    MAX_MODELS        1024
  228. #define    MAX_FILES        1024
  229. #define    MAX_DATA_PATH        64
  230.  
  231. #define    MAX_PARMS    8
  232.  
  233.  
  234. #define    TOP_PRIORITY    6
  235. #define    NOT_PRIORITY    4
  236.  
  237. //============================================================================
  238.  
  239. typedef int func_t;
  240. typedef int string_t;
  241.  
  242. typedef enum {
  243.   ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer
  244. } __packed etype_t;
  245.  
  246. #define    OFS_NULL        0
  247. #define    OFS_RETURN        1
  248. #define    OFS_PARM0        4                           // leave 3 ofs for each parm to hold vectors
  249. #define    OFS_PARM1        7
  250. #define    OFS_PARM2        10
  251. #define    OFS_PARM3        13
  252. #define    OFS_PARM4        16
  253. #define    OFS_PARM5        19
  254. #define    OFS_PARM6        22
  255. #define    OFS_PARM7        25
  256. #define    RESERVED_OFS        28
  257.  
  258. enum {
  259.   OP_DONE,
  260.   OP_MUL_F,
  261.   OP_MUL_V,
  262.   OP_MUL_FV,
  263.   OP_MUL_VF,
  264.   OP_DIV_F,
  265.   OP_ADD_F,
  266.   OP_ADD_V,
  267.   OP_SUB_F,
  268.   OP_SUB_V,
  269.  
  270.   OP_EQ_F,
  271.   OP_EQ_V,
  272.   OP_EQ_S,
  273.   OP_EQ_E,
  274.   OP_EQ_FNC,
  275.  
  276.   OP_NE_F,
  277.   OP_NE_V,
  278.   OP_NE_S,
  279.   OP_NE_E,
  280.   OP_NE_FNC,
  281.  
  282.   OP_LE,
  283.   OP_GE,
  284.   OP_LT,
  285.   OP_GT,
  286.  
  287.   OP_LOAD_F,
  288.   OP_LOAD_V,
  289.   OP_LOAD_S,
  290.   OP_LOAD_ENT,
  291.   OP_LOAD_FLD,
  292.   OP_LOAD_FNC,
  293.  
  294.   OP_ADDRESS,
  295.  
  296.   OP_STORE_F,
  297.   OP_STORE_V,
  298.   OP_STORE_S,
  299.   OP_STORE_ENT,
  300.   OP_STORE_FLD,
  301.   OP_STORE_FNC,
  302.  
  303.   OP_STOREP_F,
  304.   OP_STOREP_V,
  305.   OP_STOREP_S,
  306.   OP_STOREP_ENT,
  307.   OP_STOREP_FLD,
  308.   OP_STOREP_FNC,
  309.  
  310.   OP_RETURN,
  311.   OP_NOT_F,
  312.   OP_NOT_V,
  313.   OP_NOT_S,
  314.   OP_NOT_ENT,
  315.   OP_NOT_FNC,
  316.   OP_IF,
  317.   OP_IFNOT,
  318.   OP_CALL0,
  319.   OP_CALL1,
  320.   OP_CALL2,
  321.   OP_CALL3,
  322.   OP_CALL4,
  323.   OP_CALL5,
  324.   OP_CALL6,
  325.   OP_CALL7,
  326.   OP_CALL8,
  327.   OP_STATE,
  328.   OP_GOTO,
  329.   OP_AND,
  330.   OP_OR,
  331.  
  332.   OP_BITAND,
  333.   OP_BITOR
  334. } __packed;
  335.  
  336. typedef struct statement_s {
  337.   unsigned short int op;
  338.   short int a, b, c;
  339. } __packed dstatement_t;
  340.  
  341. typedef struct {
  342.   unsigned short int type;                                   // if DEF_SAVEGLOBGAL bit is set
  343.   // the variable needs to be saved in savegames
  344.  
  345.   unsigned short int ofs;
  346.   int s_name;
  347. } __packed ddef_t;
  348.  
  349. #define    DEF_SAVEGLOBGAL    (1<<15)
  350.  
  351. typedef struct {
  352.   int first_statement;                                   // negative numbers are builtins
  353.  
  354.   int parm_start;
  355.   int locals;                                       // total ints of parms + locals
  356.  
  357.   int profile;                                       // runtime
  358.  
  359.   int s_name;
  360.   int s_file;                                       // source file defined in
  361.  
  362.   int numparms;
  363.   unsigned char parm_size[MAX_PARMS];
  364. } __packed dfunction_t;
  365.  
  366. #define    PROG_VERSION    6
  367. typedef struct {
  368.   int version;
  369.   int crc;                                       // check of header file
  370.  
  371.   int ofs_statements;
  372.   int numstatements;                                   // statement 0 is an error
  373.  
  374.   int ofs_globaldefs;
  375.   int numglobaldefs;
  376.  
  377.   int ofs_fielddefs;
  378.   int numfielddefs;
  379.  
  380.   int ofs_functions;
  381.   int numfunctions;                                   // function 0 is an empty
  382.  
  383.   int ofs_strings;
  384.   int numstrings;                                   // first string is a null string
  385.  
  386.   int ofs_globals;
  387.   int numglobals;
  388.  
  389.   int entityfields;
  390. } __packed dprograms_t;
  391.  
  392. //=============================================================================
  393.  
  394. // offsets are allways multiplied by 4 before using
  395. typedef int gofs_t;                                   // offset in global data block
  396.  
  397. typedef struct function_s function_t;
  398.  
  399. typedef struct type_s {
  400.   etype_t type;
  401.   struct def_s *def;                                   // a def that points to this type
  402.  
  403.   struct type_s *next;
  404. // function types are more complex
  405.   struct type_s *aux_type;                               // return type or field type
  406.  
  407.   int num_parms;                                   // -1 = variable args
  408.  
  409.   struct type_s *parm_types[MAX_PARMS];                           // only [num_parms] allocated
  410.  
  411. } __packed type_t;
  412.  
  413. typedef struct def_s {
  414.   type_t *type;
  415.   char *name;
  416.   struct def_s *next;
  417.  
  418.   struct def_s *search_next;                               // for finding faster
  419.  
  420.   gofs_t ofs;
  421.   struct def_s *scope;                                   // function the var was defined in, or NULL
  422.  
  423.   int initialized;                                   // 1 when a declaration included "= immediate"
  424.  
  425. } __packed def_t;
  426.  
  427. //=============================================================================
  428.  
  429. typedef union eval_s {
  430.   string_t string;
  431.   float _float;
  432.   float vector[3];
  433.   func_t function;
  434.   int _int;
  435.   union eval_s *ptr;
  436. } __packed eval_t;
  437.  
  438. struct function_s {
  439.   int builtin;                                       // if non 0, call an internal function
  440.  
  441.   int code;                                       // first statement
  442.  
  443.   char *file;                                       // source file with definition
  444.  
  445.   int file_line;
  446.   struct def_s *def;
  447.   int parm_ofs[MAX_PARMS];                               // allways contiguous, right?
  448.  
  449. } __packed;
  450.  
  451. //
  452. // output generated by prog parsing
  453. //
  454. typedef struct {
  455.   char *memory;
  456.   int max_memory;
  457.   int current_memory;
  458.   type_t *types;
  459.  
  460.   def_t def_head;                                   // unused head of linked list
  461.  
  462.   def_t *def_tail;                                   // add new defs after this and move it
  463.  
  464.   def_t *search;                                   // search chain through defs
  465.  
  466.   int size_fields;
  467. } __packed pr_info_t;
  468.  
  469. typedef struct {
  470.   char *name;
  471.   char *opname;
  472.   float priority;
  473.   bool right_associative;
  474.   def_t *type_a, *type_b, *type_c;
  475. } __packed opcode_t;
  476.  
  477. //============================================================================
  478.  
  479. typedef enum {
  480.   tt_eof,                                       // end of file reached
  481.    tt_name,                                       // an alphanumeric name token
  482.    tt_punct,                                       // code punctuation
  483.    tt_immediate,                                   // string, float, vector
  484. } __packed token_type_t;
  485.  
  486. #define    G_FLOAT(o) (pr_globals[o])
  487. #define    G_INT(o) (*(int *)&pr_globals[o])
  488. #define    G_VECTOR(o) (&pr_globals[o])
  489. #define    G_STRING(o) (strings + *(string_t *)&pr_globals[o])
  490. #define    G_FUNCTION(o) (*(func_t *)&pr_globals[o])
  491.  
  492. //=============================================================================
  493. #endif
  494.